/**
 * 組織管理コントローラー
 * 
 * 1.管理者の場合、すべてのユーザーを取得し、ユーザーの卸情報の取得、変更、削除
 * 2.一般利用者の場合、固定のユーザーを返します。ユーザーの卸情報を取得、変更、削除
 */
package jp.veeva.jtsyka.controller;

import java.io.Serializable;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import jp.veeva.jtsyka.model.CustomerKey;
import jp.veeva.jtsyka.model.Organization;
import jp.veeva.jtsyka.model.TreeNodes;
import jp.veeva.jtsyka.model.WhsmstKey;
import jp.veeva.jtsyka.service.CustomerService;
import jp.veeva.jtsyka.service.OrganizationService;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

@Controller
public class OrganizationController implements Serializable {

    static final Logger         log              = LoggerFactory.getLogger(OrganizationController.class);

    private static final long   serialVersionUID = -1L;

    @Autowired
    private OrganizationService organizationService;
    @Autowired
    private CustomerService     customerService;

    private String              startDate;
    private String              name;
    private String              id;
    private String              pId;
    private String              whsCd;

    /**
     * 画面ロード
     * 
     * @param organization
     * @param model
     * @param request
     * @param response
     * @return Customers
     */
    @RequestMapping(value = "/organization", method = RequestMethod.GET)
    public String loadOrganization(@ModelAttribute("organization") CustomerKey customerKey, ModelMap model, HttpServletRequest request,
                                   HttpServletResponse response) {
        log.debug("画面ロード開始: " + customerKey.toString());

        // 日付設定
        String strDate = getCurrentDate();
        model.addAttribute("searchDate", strDate);

        // ユーザーを取得
        customerKey.setTradeStartDay(new Date());
        // TODO ユーザー権限により会社IDを設定、管理者の場合設定しない
        // customerKey.setCustomerCd(customerCd);

        model.addAttribute("customerList", customerService.listCustomer(customerKey));

        log.debug("画面ロード終了： " + model.toString());
        return "organization";
    }

    /**
     * 卸会社取得
     * 
     * @param request
     * @return organizations
     * @throws Exception
     */
    @RequestMapping(value = "/organizationList", method = RequestMethod.GET, produces = "text/plain;charset=UTF-8")
    public @ResponseBody String getOrganizationList(CustomerKey customerKey, HttpServletRequest request) throws Exception {
        log.debug("卸会社取得:" + request.getParameterMap().toString());

        // CustomerCd
        String customerCd = new String();
        if (null == request.getParameter("customerCd") || request.getParameter("customerCd").equals("")) {
            log.error("取引先会社がありません。");
            return null;
        } else {
            if (request.getParameter("customerCd") == "0") {
                return null;
            } else {
                customerCd = request.getParameter("customerCd");
            }
        }
        customerKey.setCustomerCd(customerCd);

        // 開始日基準日
        if (null == request.getParameter("startDate") || request.getParameter("startDate").equals("")) {
            // 本日の日付を設定
            customerKey.setTradeStartDay(new Date());
        } else {
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            Date date = formatter.parse(request.getParameter("startDate"));

            customerKey.setTradeStartDay(date);
        }

        List<String> whsList = new ArrayList<String>();

        // DBから卸会社の組織を取得する。
        whsList = customerService.getWhsList(customerKey);

        // jsonデータに変更、Ajaxに渡す。
        Gson gson = new GsonBuilder().setPrettyPrinting().create();
        String json = gson.toJson(whsList);

        log.info("取得した卸会社:" + json);
        return json;
    }

    /**
     * 卸会社詳細情報を取得する。
     * 
     * @param whsmstKey
     * @param model
     * @param request
     * @param response
     * @return Organization Info Json data
     * @throws Exception
     */
    @RequestMapping(value = "/organizationInfo", method = RequestMethod.GET)
    public @ResponseBody String getOrganizationIfo(@ModelAttribute("WhsmstKey") WhsmstKey whsmstKey, ModelMap model, HttpServletRequest request,
                                                   HttpServletResponse response) throws Exception {
        log.debug("卸会社詳細情報取得開始: " + request.getParameterMap().toString());

        // ユーザーを取得
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        Date date = formatter.parse(request.getParameter("startDate"));
        whsmstKey.setEffStartDate(date);
        // TODO ユーザー権限により会社IDを設定、管理者の場合設定しない
        // customerKey.setCustomerCd(customerCd);
        List<String> whsInfo = new ArrayList<String>();
        if (!request.getParameter("whsCd").equals("0")) {
            String regex = "-";
            String[] cds = request.getParameter("whsCd").split(regex, 0);
            String whsCd = cds[0];
            String whsSubCd = cds[1];

            whsmstKey.setWhsCd(whsCd);
            whsmstKey.setWhsSubCd(whsSubCd);

            whsInfo = organizationService.listOrganization(whsmstKey);
        }

        // jsonデータに変更、Ajaxに渡す。
        GsonBuilder gb = new GsonBuilder();
        gb.setDateFormat("yyyy/MM/dd");
        Gson gson = gb.setPrettyPrinting().create();

        String json = gson.toJson(whsInfo);

        log.debug("卸会社詳細情報取得終了： " + json);
        return json;
    }

    /**
     * Treeデータを取得、画面に返す
     * 
     * @param request
     * @param treeNodes
     * @return Json Tree data
     * @throws Exception
     */
    @RequestMapping(value = "/organizationNode", method = RequestMethod.GET, produces = "text/plain;charset=UTF-8")
    public @ResponseBody String organizationNode(HttpServletRequest request, TreeNodes treeNodes) throws Exception {
        log.debug("Tree dataを取得: " + request.getParameterMap().toString());

        // 卸会社コード
        String whsCd = new String();
        if (null == request.getParameter("whsCd") || request.getParameter("whsCd").equals("")) {
            log.error("卸会社コードがありません。");
            // TODO エラー返す
            return null;
        } else {
            whsCd = request.getParameter("whsCd");
        }

        startDate = new String();
        if (null == request.getParameter("startDate") || request.getParameter("startDate").equals("")) {
            // 本日の日付を設定
            Calendar cal = Calendar.getInstance();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
            startDate = sdf.format(cal.getTime());
        } else {
            startDate = request.getParameter("startDate");
        }

        // サービスより組織コード、組織名称、組織リレーションを取得する。
        List<String> lstTree1 = new ArrayList<String>();
        // 取得するかリフレッシュするか
        // 該当ノードのID
        String id = new String();
        id = request.getParameter("id");
        if (null == request.getParameter("pId") || request.getParameter("pId").equals("")) {
            log.info("根ノード更新");
            // 根ノード とその子供
            lstTree1 = organizationService.listOrganizationRel(whsCd, id);
        } else {
            log.info("Tree操作後該当ノードをリフレッシュします。");
            // 該当ノードのみ
            lstTree1 = organizationService.refreshOrganizationTree(whsCd, id);
        }

        log.debug("lstTree1:" + lstTree1);

        // jsonデータに変更
        Gson gson = new GsonBuilder().setPrettyPrinting().create();
        String json = gson.toJson(lstTree1);

        log.info("Tree再取得。返却値:" + json);
        return json;
    }

    /**
     * 組織を追加する。
     * 
     * @param request
     * @return
     */
    @RequestMapping(value = "/organizationNode", method = RequestMethod.POST)
    public @ResponseBody String organizationAddNodes(Organization organization, @RequestParam HttpServletRequest request) {
        log.info("Ajax 組織追加開始");
        log.debug("Requestparam: " + request.toString());
        name = new String();
        id = new String();
        pId = new String();
        whsCd = new String();
        startDate = new String();

        if (null != request.getParameter("whsCd") && !request.getParameter("whsCd").equals("")) {
            whsCd = request.getParameter("whsCd");
        }
        if (null != request.getParameter("startDate") && !request.getParameter("startDate").equals("")) {
            startDate = request.getParameter("startDate");
        }
        if (null != request.getParameter("name") && !request.getParameter("name").equals("")) {
            name = request.getParameter("name");
        }
        if (null != request.getParameter("id") && !request.getParameter("id").equals("")) {
            id = request.getParameter("id");
        } else {
            
            return null;
        }
        // パラメータ設定
        organization.setWhsVeevaOrgCd(id);
        organization.setWhsCd(whsCd);
        organization.setWhsSubCd(request.getParameter("whsSubCd"));
        organization.setWhsOrgNm(name);
        organization.setWhsOrgCd(request.getParameter("whsOrgCd"));
        organization.setWhsDepoCd(request.getParameter("whsDepoCd"));
        organization.setWhsDepoCdSeq(new BigDecimal(request.getParameter("whsDepoCdSeq")));
        organization.setIsPrimaryNode(0);

        // 組織マスター、組織リレーションテーブルに組織を追加
        if (organizationService.addOrganization(organization)) {
            log.info("組織追加終了");
            return id;
        } else {
            log.error("組織追加エラー。");
            return null;
        }
    }

    /*
     * Treeノード名編集
     */
    @RequestMapping(value = "/organizationNodeRename", method = RequestMethod.POST)
    public @ResponseBody String organizationRenameNodes(@RequestParam Map<String, String> requestParams) {
        log.info("Ajax 組織名称変更開始");
        log.debug("Requestparam: " + requestParams.toString());
        log.info("Ajax 組織名称変更終了");
        return requestParams.get("name");
    }

    /*
     * Treeノード削除
     */
    @RequestMapping(value = "/organizationNodeDel", method = RequestMethod.POST)
    public @ResponseBody String organizationDeleteNodes(@RequestParam Map<String, String> requestParams) {
        log.info("Ajax 組織削除開始");
        log.debug("Requestparam: " + requestParams.toString());
        log.info("Ajax 組織削除終了");
        return requestParams.get("id");
    }

    /*
     * Treeノード追加
     */
    @RequestMapping(value = "/asyncDragNodes", method = RequestMethod.POST)
    public @ResponseBody String asyncDragNodes(@RequestParam Map<String, String> requestParams) {
        log.info("Ajax Drag-Drop開始");
        log.debug("Requestparam: " + requestParams.toString());
        log.info("Ajax Drag-Drop終了");
        return requestParams.get("id");
    }

    private String getCurrentDate() {
        String date = new String();
        // 現在の日付を取得する。
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        date = sdf.format(cal.getTime());
        return date;
    }
}
